package com.ly.cloud.utils;

import java.io.Serializable;

import java.text.DateFormat;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
 * 日期处理工具
 * @author caihuihai
 * @date 2018年12月12日 下午4:21:30
 */
public class DatetimeUtils implements Serializable {
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_FORMAT_CHINA = "yyyy年MM月dd日";
    public static final String TIME_FORMAT = "HH:mm:ss";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_YEAR = "yyyy";

    /**
     * 从日期得到带格式的日期字符串
     * @param date
     * @return
     */
    public static String getDateStr(Date date) {
        if (date == null) {
            return "";
        } else {
            try {
                DateFormat df =
                    new SimpleDateFormat(DatetimeUtils.DATE_FORMAT);
                return df.format(date);
            } catch (Exception ex) {

                return "";
            }
        }
    }

    /**
     * 从日期得到带格式的时间字符串
     * @param date
     * @return
     */
    public static String getTimeStr(Date date) {
        if (date == null) {
            return "";
        } else {
            try {
                DateFormat df =
                    new SimpleDateFormat(DatetimeUtils.TIME_FORMAT);
                return df.format(date);
            } catch (Exception ex) {
                return "";
            }
        }
    }

    public static String getCurrentDateTimeStr() {
        return DatetimeUtils.getDateFormatStr(DatetimeUtils.DATE_TIME_FORMAT,
                                              new Date());
    }

    /**
     * Date转具体时间
     * @param date
     * @return
     */
    public static String getDateTimeStr(Date date) {
        if (date == null) {
            return "";
        } else {
            try {
                Calendar c = Calendar.getInstance();
                c.setTime(date);
                int dayofyear = c.get(Calendar.DAY_OF_YEAR); //从1开始
                int second =
                    c.get(Calendar.SECOND); //时间秒从0开始59结束，试验结果是这样的，但是api文档说是从1开始

                DateFormat df = null;
                if (dayofyear > 0 && second >= 0) {
                    df = new SimpleDateFormat(DatetimeUtils.DATE_TIME_FORMAT);
                } else {
                    df = new SimpleDateFormat(DatetimeUtils.DATE_FORMAT);
                }
                return df.format(date);
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        }
    }


    /**
     * 日期String转Date
     * @param date
     * @return
     */
    public static Date getDateFromStr(String date) {
        if (date == null || date.equals("")) {
            return null;
        } else {
            try {
                DateFormat df =
                    new SimpleDateFormat(DatetimeUtils.DATE_FORMAT);
                return df.parse(date);
            } catch (Exception ex) {
                return DatetimeUtils.getCurrenDate(DatetimeUtils.DATE_FORMAT);
            }
        }
    }


    public static Date getDatetimeFromStr(String date) {
        if (date == null || date.equals("")) {
            return null;
        } else {
            try {
                DateFormat df = null;
                if (date.length() <= 10) { //如果只有日期则长度肯定小于10
                    df = new SimpleDateFormat(DatetimeUtils.DATE_FORMAT);
                } else {
                    df = new SimpleDateFormat(DatetimeUtils.DATE_TIME_FORMAT);
                }
                return df.parse(date);
            } catch (Exception ex) {

                return DatetimeUtils.getCurrenDate(DatetimeUtils.DATE_TIME_FORMAT);
            }
        }
    }


    public static Date getDate(String date) {
        if (date == null || date.equals("")) {
            return null;
        } else {
            try {
                DateFormat df =
                    new SimpleDateFormat(DatetimeUtils.DATE_FORMAT);
                return df.parse(date);
            } catch (Exception ex) {
                try {
                    DateFormat df =
                        new SimpleDateFormat(DatetimeUtils.DATE_TIME_FORMAT);
                    return df.parse(date);
                } catch (Exception e) {
                    ex.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String getCurrentDateFromFormat(String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(new Date());
    }

    public static String[] getDayPeriod() {
        String start = DatetimeUtils.getDateStr(new Date()) + " 00:00:00.001";
        String end = DatetimeUtils.getDateStr(new Date()) + " 23:59:59.999";
        String[] period = new String[2];
        period[0] = start;
        period[1] = end;
        return period;
    }

    public static String[] getWeekPeriod() {
        Calendar cs = Calendar.getInstance();
        cs.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        String start = DatetimeUtils.getDateStr(cs.getTime());
        Calendar ce = Calendar.getInstance();
        ce.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        String end = DatetimeUtils.getDateStr(ce.getTime());
        String[] period = new String[2];
        period[0] = start;
        period[1] = end;
        return period;
    }


    /**
     * 判断现在是星期几
     * @return
     */
    public String getWeekDayString() {
        String weekString = "";
        final String dayNames[] =
        { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar calendar = Calendar.getInstance();
        Date date = new Date();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        weekString = dayNames[dayOfWeek - 1];
        return weekString;
    }

    public static String[] getMonthPeriod() {
        Calendar yc = Calendar.getInstance();
        String year = String.valueOf(yc.get(Calendar.YEAR));
        Calendar cl = Calendar.getInstance();
        int lastDay = cl.getActualMaximum(Calendar.DAY_OF_MONTH);

        int month = cl.get(Calendar.MONTH) + 1;
        //System.out.println("month="+month);
        String start = "", end = "";
        if (month < 10) {
            start = year + "-0" + String.valueOf(month) + "-01 00:00:00.001";
        } else {
            start = year + "-" + String.valueOf(month) + "-01 00:00:00.001";
        }

        if (month < 10) {
            end =
year + "-0" + String.valueOf(month) + "-" + String.valueOf(lastDay) +
  " 23:59:59.999";
        } else {
            end =
year + "-" + String.valueOf(month) + "-" + String.valueOf(lastDay) +
  " 23:59:59.999";
        }


        String[] period = new String[2];
        period[0] = start;

        period[1] = end;
        return period;
    }

    //根据输入的日期得到月期间

    public static String[] getMonthPeriod(Date date) {
        Calendar yc = Calendar.getInstance();
        yc.setTime(date);

        String year = String.valueOf(yc.get(Calendar.YEAR));
        Calendar cl = Calendar.getInstance();
        cl.setTime(date);
        int lastDay = cl.getActualMaximum(Calendar.DAY_OF_MONTH);

        int month = cl.get(Calendar.MONTH) + 1;
        //System.out.println("month="+month);
        String start = "", end = "";
        if (month < 10) {
            start = year + "-0" + String.valueOf(month) + "-01 00:00:00";
        } else {
            start = year + "-" + String.valueOf(month) + "-01 00:00:00";
        }

        if (month < 10) {
            end =
year + "-0" + String.valueOf(month) + "-" + String.valueOf(lastDay) +
  " 23:59:59";
        } else {
            end =
year + "-" + String.valueOf(month) + "-" + String.valueOf(lastDay) +
  " 23:59:59";
        }

        String[] period = new String[2];
        period[0] = start;

        period[1] = end;
        return period;
    }

    public static Date getCurrenDate(String pattern) {
        if (pattern == null) {
            pattern = "";
        }
        if ("".equals(pattern)) {
            return new Date();
        }
        return DatetimeUtils.formateDate(new Date(), pattern);
    }


    public static Date formateDate(Date date, String pattern) {
        if (pattern == null) {
            pattern = "";
        }

        try {
            if (!"".equals(pattern)) {
                DateFormat df = new SimpleDateFormat(pattern);
                String tmp = df.format(date);
                return df.parse(tmp);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return date;
    }

    public static Date formateDate(String date, String pattern) {
        if (pattern == null) {
            pattern = "";
        }
        Date temp = null;
        try {
            if (!"".equals(pattern)) {
                DateFormat df = new SimpleDateFormat(pattern);
                temp = df.parse(date);
                return temp;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return temp;
    }

    public static String getCurrentDateStr() {
        return DatetimeUtils.getDateTimeStr(new Date());
    }

    //得到明天的字符串

    public static String getTomorrowStr() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_YEAR, 1);
        Date date = c.getTime();
        return getDateStr(date);
    }

    public static Date getTomorrowDate() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_YEAR, 1);
        return c.getTime();
    }
    //在某个日期上加减日期

    public static Date dateAddOrMin(Date date, int number) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_YEAR, number);
        return c.getTime();
    }



    /**
     * 根据字符串获取年份
     * @param dateStr
     * @return
     */
    public static int getYearFormatPattern(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = GregorianCalendar.getInstance();

        try {
            calendar.setTime(sdf.parse(dateStr));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int year = calendar.get(Calendar.YEAR);
        return year;
    }

    /**
     * 根据字符串获取月
     * @param dateStr
     * @return
     */
    public static int getMonthFormatPattern(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = GregorianCalendar.getInstance();

        try {
            calendar.setTime(sdf.parse(dateStr));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int month = calendar.get(Calendar.MONTH) + 1;
        return month;
    }

    /**
     * 根据字符串获取日期
     * @param dateStr
     * @return
     */
    public static int getDateFormatPattern(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = GregorianCalendar.getInstance();

        try {
            calendar.setTime(sdf.parse(dateStr));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int date = calendar.get(Calendar.DATE);
        return date;
    }

    /**
     * 根据开始日期和结束日期，获取该时间内所有的日期集合
     * @param sDate 开始日期
     * @param eDate  结束日期
     * @return
     */
    public static List<Date> getDates(Date sDate, Date eDate) {
        List lDate = new ArrayList();
        lDate.add(sDate);
        Calendar cal = Calendar.getInstance();
        //使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(sDate);
        boolean bContinue = true;
        while (bContinue) {
            //根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (eDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(eDate);
        return lDate;
    }

    /**
     * 根据开始日期和结束日期，获取该时间内所有的日期集合
     * @param sDate 开始日期
     * @param eDate  结束日期
     * @return
     */
    public static List<Date> getDates(String sDateStr, String eDateStr) {
        Date sDate = getDateFromStr(sDateStr);
        Date eDate = getDateFromStr(eDateStr);

        List lDate = new ArrayList();
        lDate.add(sDate);
        Calendar cal = Calendar.getInstance();
        //使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(sDate);
        boolean bContinue = true;
        while (bContinue) {
            //根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (eDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(eDate);
        return lDate;
    }

    /**
     * 把2014-6-14转换成2014-06-14
     * @param dateStr
     * @param pattern
     * @return
     */
    public static String formatDateStr(String dateStr) {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date dDate = null;
        try {
            dDate = format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        DateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
        String reDate = format2.format(dDate);
        return reDate;
    }

    /**
     * 比较两个日期大小
     * @param d1
     * @param d2
     * @return d1>d2:返回1；d1<d2：返回-1；否则返回0
     */
    public static int compareDate(String d1, String d2) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date dt1 = df.parse(d1);
            Date dt2 = df.parse(d2);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    /**
     *比较两个日期大小
     * @param d1
     * @param d2
     * @return d1>d2:返回1；d1<d2：返回-1；否则返回0
     */
    public static int compareDate(Date d1, Date d2) {
        if (d1 == null || d2 == null) {
            return 0;
        }
        try {
            if (d1.getTime() >= d2.getTime()) {
                return 1;
            } else if (d1.getTime() <= d2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    //==============================================================================

    /**
     * 得到两天的差，后者减前者（date2 - date1）
     * @param date1
     * @param date2
     * @return
     */
    public static long getDiffDay(Date date1, Date date2) {
        try {
            long DAY = 24L * 60L * 60L * 1000L;
            return ((date2.getTime() - date1.getTime()) / DAY);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0L;
    }

    /**
     * 根据日期字符串获取日期，
     * @param string   时间字符串
     * @param format   字符串格式
     * @return
     */
    public static Date getDate(String string, String format) {
        Date date = null;
        SimpleDateFormat formatDate = new SimpleDateFormat(format);
        try {
            if (string != null && (!"".equals(string))) {
                date = formatDate.parse(string);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * 甘修瑞
     * 将日期字符串转换为新的格式
     * System.out.println(getDateStr("2014-04-12","yyyy-MM-dd","yyyy年MM月dd日"))
     * @param string   时间字符串
     * @param format1   旧日期格式
     * @param format2   新日期格式
     * @return
     */
    public static String getDateFormatStr(String datestring, String format1,
                                          String format2) {
        Date date = new Date();
        if (datestring == null && datestring.equals("")) {
            return null;
        }

        SimpleDateFormat formatDate1 = new SimpleDateFormat(format1); //格式1
        try {
            date = formatDate1.parse(datestring);
        } catch (ParseException e) {
            e.printStackTrace();
            //System.out.println("调用公共的日期格式转换方法时，提供了错误的格式。");
            //ADFUtils.LOGGER.severe("调用公共的日期格式转换方法时，提供了错误的格式。");
        }

        SimpleDateFormat formatDate2 = new SimpleDateFormat(format2); //格式2
        String dateStr = formatDate2.format(date);

        return dateStr;
    }


    /**
     * 获取某个格式的日期的字符串
     * @param format  格式
     * @param date   日期
     * @return   格式化的字符串
     */
    public static String getDateFormatStr(String format, Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }


    /**
     * 2014年9月5日 彭金、周连武添加
     *比较当前日期是否在给定的时间范围范围内，date1一定小于date2
     * @param before 前面时间字符串
     * @param after  后面时间字符串
     * @param flag  如果为1表示字符格式为YYYY-MM-DD HH:MM:SS  为2表示字符格式为YYYY-MM-DD
     * @return
     */
    public static boolean curtimeInPeriod(String before, String after,
                                          int flag) {
        if (StringUtils.isNotBlank(before) && StringUtils.isNotBlank(after)) {
            if (flag == 1) {
                Date beforedate =
                    DatetimeUtils.getDate(before, DatetimeUtils.DATE_TIME_FORMAT);
                Date afterdate =
                    DatetimeUtils.getDate(after, DatetimeUtils.DATE_TIME_FORMAT);
                return DatetimeUtils.curtimeInPeriod(beforedate, afterdate,
                                                     flag);
            } else if (flag == 2) {
                Date beforedate =
                    DatetimeUtils.getDate(before, DatetimeUtils.DATE_FORMAT);
                Date afterdate =
                    DatetimeUtils.getDate(after, DatetimeUtils.DATE_FORMAT);
                return DatetimeUtils.curtimeInPeriod(beforedate, afterdate,
                                                     flag);
            }
            //
        }
        return false;
    }

    /**
     * 2014年9月5日 彭金、周连武添加
     *比较当前日期是否在给定的时间范围范围内，date1一定小于date2
     * @param before 前面时间字符串
     * @param after  后面时间字符串
     * @param flag  如果为1表示字符格式为YYYY-MM-DD HH:MM:SS  为2表示字符格式为YYYY-MM-DD
     * @return  在中间表示true 否则flase
     */
    public static boolean curtimeInPeriod(Date before, Date after, int flag) {
        if (before == null || after == null) {
            return false;
        }
        Date curr = null;
        if (flag == 1) {
            curr = DatetimeUtils.getCurrenDate(DatetimeUtils.DATE_TIME_FORMAT);
        } else {
            curr = DatetimeUtils.getCurrenDate(DatetimeUtils.DATE_FORMAT);
            //因为当Date格式是年月日，使用getTime()获取到的是这天00：00：00的毫秒值，
            //所以结束日期必须在加1天，这样才能将指定结束日期包含进来
            Calendar c = Calendar.getInstance();  
            c.setTime(after);  
            c.add(Calendar.DAY_OF_MONTH, 1);// 结束日期+1天
            after = DatetimeUtils.formateDate(c.getTime(), DATE_FORMAT);
        }

        if ((DatetimeUtils.compareDate(curr, before) == 1) &&
            (DatetimeUtils.compareDate(curr, after) == -1)) {
            return true;
        }

        return false;
    }

    /**
     * 根据开始日期和结束日期，获取该时间内所有的日期集合
     * @param sDate 开始日期
     * @param eDate  结束日期
     * @return
     */
    public static List<Date> getAllDatesBetweeStoE(Date sDate, Date eDate) {
        List lDate = new ArrayList();
        lDate.add(sDate);
        Calendar cal = Calendar.getInstance();
        //使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(sDate);
        boolean bContinue = true;
        while (bContinue) {
            //根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (eDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        lDate.add(eDate);
        return lDate;
    }

    /**
     * 根据当前时间判断
     * @param date  日期
     * @return  星期几
     */
    public static int isXqjofDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        /* 
         * java中返回值，1是星期日、2是星期一、3是星期二、4是星期三、5是星期四、6是星期五、7是星期六
         * 为了直观需转换，7是星期日、1是星期一、2是星期二、3是星期三、4是星期四、5是星期五、6是星期六
         * caihuihai @2018-12-13
         * */
        int myweek = week-1;
        if(week-1 == 0) {
        	myweek = 7;
        }
        return myweek;
        //return week;
    }

    public static void main(String[] args) {
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String str = "2018-12-13";
        Date date = null;
		try {
			date = sdf.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		System.out.println(str+"，是星期几："+isXqjofDate(date));
        
    }

}
